﻿/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is tyzoh.jp code.
 *
 * The Initial Developer of the Original Code is Kazutaka Kurihara.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */
using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using Qurihara;
using Qurihara.Anm;
using System.Xml;

namespace Qurihara
{
	/// <summary>
	/// ViewSnap の概要の説明です。
	/// </summary>
	public class ViewSnap
	{
		protected Rectangle viewRectangle;
		protected string name;
		//protected ToolBarButton button;
		//protected ToolBar parentToolBar;
		//protected IKotodamaBase kotodama;
		protected Qurihara.View parentView;
		//public ViewSnap(string n, Rectangle view,ToolBar bar,IKotodamaBase koto)
		public ViewSnap(string n, Rectangle view,Qurihara.View pView)
		{
			name = n;
			viewRectangle = view;
			//button = new ToolBarButton(name);
			//parentToolBar = bar;
			//kotodama = koto;
			parentView = pView;

			Initialize();
		}
		public void Initialize()
		{
			//button.Text = name;
			//parentToolBar.Buttons.Add(button);
			//parentToolBar.ButtonClick += new ToolBarButtonClickEventHandler(parentToolBar_ButtonClick);
			//ToolBarDock.ToolBarDockHolder holder = kotodama.ToolBarManager.GetHolder(parentToolBar);
			//holder.UpdateSize();
		}
		public void Dispose()
		{
			//parentToolBar.Buttons.Remove(button);
			//parentToolBar.ButtonClick -= new ToolBarButtonClickEventHandler(parentToolBar_ButtonClick);
			//ToolBarDock.ToolBarDockHolder holder = kotodama.ToolBarManager.GetHolder(parentToolBar);
			//holder.UpdateSize();
		}
		public string Name
		{
			get{return name;}
			set{name = value;}
		}
		public Rectangle ViewRectangle
		{
			get{return viewRectangle;}
		}
		public override string ToString()
		{
			return name;
		}
		public void Go()
		{
			if(!parentView.ViewRectangle.Equals(viewRectangle))
			{
				Rectangle re;

				//re = kotodama.Presentation.CurrentSlide.View.ViewRectangle;
				re = parentView.ViewRectangle;
				Point p1 = new Point(re.Left+re.Width/2,re.Top+re.Height/2);
				Point p2 = new Point(viewRectangle.Left+viewRectangle.Width/2,viewRectangle.Top+viewRectangle.Height/2);
				Point p3 = new Point((p1.X+p2.X)/2,(p1.Y+p2.Y)/2);
				re.X = p3.X-viewRectangle.Width;
				re.Y = p3.Y-viewRectangle.Height;
				re.Width = viewRectangle.Width*2;
				re.Height = viewRectangle.Height*2;
				RectMoveAnm anm = new RectMoveAnm(
					//(IAnmElement)kotodama.Presentation.CurrentSlide.View,
					(IAnmElement)parentView,
					//kotodama.Presentation.CurrentSlide.View.ViewRectangle,
					parentView.ViewRectangle,
					re,800,RectMoveAnm.AnmType.Linear);
				anm.AnmFinishedHandler+=new EventHandler(anm_AnmFinishedHandler);
				anm.Start();
			}
		}

        public void GoLinear()
        {
            if (!parentView.ViewRectangle.Equals(viewRectangle))
            {
                RectMoveAnm anm = new RectMoveAnm(
                    (IAnmElement)parentView,
                    parentView.ViewRectangle,
                    this.viewRectangle,
                    1600, RectMoveAnm.AnmType.Linear);
                anm.Start();
            }
        }

		public void Warp()
		{
			//kotodama.Presentation.CurrentSlide.View.ViewRectangle = viewRectangle;
			parentView.ViewRectangle = viewRectangle;
		}
		public void Save(XmlTextWriter xtw)
		{
			xtw.WriteStartElement("viewsnap");
			xtw.WriteElementString("name", name);
			xtw.WriteElementString("rect_x", viewRectangle.X.ToString());
			xtw.WriteElementString("rect_y", viewRectangle.Y.ToString());
			xtw.WriteElementString("rect_w", viewRectangle.Width.ToString());
			xtw.WriteElementString("rect_h", viewRectangle.Height.ToString());
			xtw.WriteEndElement(); // /viewsnap
		}

		#region private fnc
//		private void parentToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
//		{
//			if (e.Button == button) Go();
//		}

		private void anm_AnmFinishedHandler(object sender, EventArgs e)
		{
			RectMoveAnm anm = new RectMoveAnm(
				//(IAnmElement)kotodama.Presentation.CurrentSlide.View,
				//kotodama.Presentation.CurrentSlide.View.ViewRectangle,
				(IAnmElement)parentView,
				parentView.ViewRectangle,
				this.viewRectangle,
				800,RectMoveAnm.AnmType.Linear);
			anm.Start();

		}
		#endregion

	}
	public class ViewSnapList : ArrayList
	{
		public ViewSnapList() :base(){}
		public ViewSnapList(string id) :base()
		{
			Id = id;
		}
		public string Id = "";

		public event SnapChangedEventHandler SnapChanged=null;
		public delegate void SnapChangedEventHandler(object sender,SnapChangedEventArgs e);
		public class SnapChangedEventArgs : EventArgs
		{
			public SnapChangedEventArgs(int snapIndex)
			{
				SnapIndex = snapIndex;
			}
			public int SnapIndex;
		}

		public event EventHandler Invalidated;
		public bool SuspendInvalidate = false;
		public void Invalidate()
		{
			if (!SuspendInvalidate && Invalidated != null) Invalidated(this,new EventArgs());
		}
		public override int Add(object value)
		{
			int ret = base.Add (value);
			Invalidate();
			return ret;
		}
		public override void Insert(int index, object value)
		{
			base.Insert (index, value);
			Invalidate();
		}
		public void Overwrite(int index, object value)
		{
			base.RemoveAt(index);
			this.Insert(index,value);
		}

		public override void Remove(object obj)
		{
			base.Remove (obj);
			Invalidate();
		}
		public override void Clear()
		{
			base.Clear ();
			Invalidate();
		}

		public void Update()
		{
			foreach(ViewSnap vs in this)
			{
				vs.Dispose();
			}
			foreach(ViewSnap vs in this)
			{
				vs.Initialize();
			}
			Invalidate();
		}
		public bool Go(int index)
		{
			if (0<= index && index < this.Count)
			{
				ViewSnap vs = (ViewSnap)this[index];
				vs.Go();
				Invalidate();
				if (SnapChanged != null) SnapChanged(this,new SnapChangedEventArgs(index));
				return true;
			}
			return false;
		}
        public bool GoWarp(int index)
        {
            if (0 <= index && index < this.Count)
            {
                ViewSnap vs = (ViewSnap)this[index];
                vs.Warp();
                Invalidate();
                if (SnapChanged != null) SnapChanged(this, new SnapChangedEventArgs(index));
                return true;
            }
            return false;
        }
        public bool GoLinear(int index)
        {
            if (0 <= index && index < this.Count)
            {
                ViewSnap vs = (ViewSnap)this[index];
                vs.GoLinear();
                Invalidate();
                if (SnapChanged != null) SnapChanged(this, new SnapChangedEventArgs(index));
                return true;
            }
            return false;
        }

		public void Save(XmlTextWriter xtw)
		{
			try
			{
//				xtw.Formatting = Formatting.Indented;
//				xtw.Indentation = 3;
//
//				xtw.WriteStartDocument();
				xtw.WriteStartElement("viewsnaplist");
				xtw.WriteAttributeString("id",Id);
				xtw.WriteAttributeString("number",this.Count.ToString());
				foreach(ViewSnap vs in this)
				{
					vs.Save(xtw);
				}				
				xtw.WriteEndElement(); // /viewsnaplist
//				xtw.WriteEndDocument();
//				xtw.Flush();
//				xtw.Close();
			}
			catch(System.Exception e)
			{
				System.Diagnostics.Debug.Fail("ViewSnapList Save Error.",e.ToString());
			}
		}

		private void readSec(XmlTextReader x,ref string n,ref string v)
		{
			x.Read(); // Element Type
			n = x.Name;
			x.Read(); // Text  Type
			n = x.Value;
			x.Read(); // endElement		
		}

		// このLoad関数はViewLogVisualizerのために残っている。
		//public void Load(XmlTextReader xtr,ToolBar bar,IKotodamaBase koto)
		//public void Load(XmlTextReader xtr,IKotodamaBase koto)
		public void Load(XmlTextReader xtr,Qurihara.View pView)
		{
			this.Clear();
			try
			{
				xtr.WhitespaceHandling = WhitespaceHandling.None;

				string eN = null;
				string eV = null ;

				while (xtr.Read() == true)
				{
					//if (xtr.Name.Equals("viewsnap"))
					if (xtr.IsStartElement("viewsnap"))
					{
						string n;
						int x,y,w,h;
						readSec(xtr,ref eN,ref eV); // name
						n = eN;
						readSec(xtr,ref eN,ref eV); // X
						x = Convert.ToInt32(eN);
						readSec(xtr,ref eN,ref eV); // Y
						y = Convert.ToInt32(eN);
						readSec(xtr,ref eN,ref eV); // Width
						w = Convert.ToInt32(eN);
						readSec(xtr,ref eN,ref eV); // Height
						h = Convert.ToInt32(eN);

						//this.Add(new ViewSnap(n,new Rectangle(x,y,w,h),bar,koto));
						//this.Add(new ViewSnap(n,new Rectangle(x,y,w,h),koto));
						this.Add(new ViewSnap(n,new Rectangle(x,y,w,h),pView));
					}
				}
				xtr.Close();
			}
			catch(System.Exception e)
			{
				System.Diagnostics.Debug.Fail("ViewSnapList Load Error.",e.ToString());
			}
			Invalidate();
		}

//		public void ProbeLoadInit()
//		{
//			this.Clear();
//		}		
		private void _ProbeLoad(XmlTextReader xtr,Qurihara.View pView)
		{		
			if (xtr.IsStartElement("viewsnap"))
			{
				string eN = null;
				string eV = null ;

				string n;
				int x,y,w,h;
				readSec(xtr,ref eN,ref eV); // name
				n = eN;
				readSec(xtr,ref eN,ref eV); // X
				x = Convert.ToInt32(eN);
				readSec(xtr,ref eN,ref eV); // Y
				y = Convert.ToInt32(eN);
				readSec(xtr,ref eN,ref eV); // Width
				w = Convert.ToInt32(eN);
				readSec(xtr,ref eN,ref eV); // Height
				h = Convert.ToInt32(eN);

				this.Add(new ViewSnap(n,new Rectangle(x,y,w,h),pView));
			}
		}
//		public void ProbeLodEnd()
//		{
//			Invalidate();
//		}

		public static ViewSnapList ProbeLoad(XmlTextReader xtr,Qurihara.View pView)
		{
			ViewSnapList newList = null;
			if (xtr.IsStartElement("viewsnaplist"))
			{
				newList = new ViewSnapList();
				newList.Id = xtr.GetAttribute("id");
				int num = int.Parse(xtr.GetAttribute("number"));
				for(int i=0;i<num;i++)
				{
					xtr.Read();//viewsnap
					newList._ProbeLoad(xtr,pView);
					xtr.Read();// /viewsnap
				}
				newList.Invalidate();
			}
			return newList;
		}

		public override string ToString()
		{
			return Id;
		}


	}
}
